package biz

import (
	"context"
	"github.com/blinkbean/dingtalk"
	"github.com/go-kratos/kratos/v2/log"
	"kratosDingTalk/internal/conf"
	"kratosDingTalk/internal/robot"
	"kratosDingTalk/pkg"
)

// Greeter is a Greeter model.
type Greeter struct {
	Hello string
}

type GreeterRepo interface {
	Save(context.Context, *Greeter) (*Greeter, error)
}

type GreeterUsecase struct {
	repo GreeterRepo
	log  *log.Helper

	// 钉钉机器人: 调用钉钉原生的API
	dingOriginApiRobot robot.IRobot

	// 钉钉机器人 使用第三方包: go get github.com/blinkbean/dingtalk_local
	dingtalk           *dingtalk.DingTalk // 不加签名 关键词过滤
	dingtalkWithSecret *dingtalk.DingTalk // 加签名 加签
}

func NewGreeterUsecase(repo GreeterRepo, logger log.Logger, robot robot.IRobot, robotConf *conf.Robot) *GreeterUsecase {
	return &GreeterUsecase{
		repo: repo,
		log:  log.NewHelper(logger),

		dingOriginApiRobot: robot,

		dingtalk:           dingtalk.InitDingTalk([]string{robotConf.GetAccessToken()}, robotConf.GetKey()),
		dingtalkWithSecret: dingtalk.InitDingTalkWithSecret(robotConf.GetAccessToken(), robotConf.GetSecret()),
	}
}

func (uc *GreeterUsecase) CreateGreeter(ctx context.Context, g *Greeter) (*Greeter, error) {
	uc.log.WithContext(ctx).Infof("CreateGreeter: %v", g.Hello)

	// Notice 在这里往钉钉机器人发送消息

	/*
		// 1、测试调用原生API发送markdown格式的数据
		// Notice 发送的数据一定要带关键词，否则会报这个错误：
		// {"errcode":310000,"errmsg":"错误描述:关键词不匹配;解决方案:请联系群管理员查看此机器人的关键词，并在发送的信息中包含此关键词;"}
		title := "测试一个发送数据" + time.Now().Format("2006-01-02 15:04:05")

		nameMap := map[string]string{
			"name1": "whw",
			"name2": "naruto",
			"name3": "sasuke",
			"name4": "whw666",
		}
		text := ""
		for key, name := range nameMap {
			text += fmt.Sprintf(" - %v: %v \n\n", key, name)
		}

		errSendMd := uc.sendMarkdownDingTalkMsg(ctx, title, text)
		if errSendMd != nil {
			// Notice 记录log、trace等
			uc.log.Errorf("调用原生API发送钉钉消息失败: err: %v", errSendMd)
		}
	*/

	// 2、测试使用第三方包发送钉钉消息
	text2 := "调用第三方包测试发一条数据123123123"
	// Notice 实际上 发送钉钉消息有时候我们会 "异步处理"，毕竟是http请求，比较耗时～
	// Notice 这里的ctx建议新建一个 不要跟主协程用同一个ctx ～ 当然大家可以根据实际情况来～
	// TODO 机器人带签名的话 使用 uc.dingtalkWithSecret 即可～
	go func() {
		// Notice 新版本已经支持加 ctx 参数了～
		// Notice ❗️注意：因为这里我使用了异步的方法发送钉钉的http请求，最好ctx不要用主协程的ctx，我这里用了 ctxWithoutCancel～
		// 这篇博客介绍过：https://www.cnblogs.com/paulwhw/p/17402387.html#_label4

		ctxWithoutCancel := pkg.WithoutCancel(ctx)
		errSend2 := uc.dingtalk.SendTextMessageWithCtx(ctxWithoutCancel, text2, dingtalk.WithAtAll())
		if errSend2 != nil {
			uc.log.Errorf("errSend2: %v", errSend2)
		}
	}()

	return uc.repo.Save(ctx, g)
}
